//===----------------------------------------------------------------------===//
//
//                         CMU-DB Project (15-445/645)
//                         ***DO NO SHARE PUBLICLY***
//
// Identification: src/include/index/index_iterator.h
//
// Copyright (c) 2018, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//
/**
 * index_iterator.h
 * For range scan of b+ tree
 */
#pragma once
#include "buffer/buffer_pool_manager.h"
#include "common/config.h"
#include "storage/page/b_plus_tree_leaf_page.h"
#include "storage/page/page_guard.h"

namespace bustub {

#define INDEXITERATOR_TYPE IndexIterator<KeyType, ValueType, KeyComparator>

INDEX_TEMPLATE_ARGUMENTS
class IndexIterator {
  using LeafPage = BPlusTreeLeafPage<KeyType, ValueType, KeyComparator>;

 public:
  // you may define your own constructor based on your member variables
  IndexIterator(ReadPageGuard &&page_guarded, int index, BufferPoolManager *bpm);
  IndexIterator(IndexIterator &&that) noexcept;
  ~IndexIterator();  // NOLINT

  // notice that IsEnd doesn't have the same meaning with tree.End(),which means the next position after the last
  // element in tree.
  auto IsEnd() -> bool;

  auto operator=(IndexIterator &&that) noexcept -> IndexIterator &;

  auto operator*() -> const MappingType &;

  auto operator++() -> IndexIterator &;

  auto operator==(const IndexIterator &itr) const -> bool {
    if (this->index_ == -1 && itr.index_ == -1) {
      return true;
    }
    return this->bpm_ == itr.bpm_ && this->page_guarded_.PageId() == itr.page_guarded_.PageId() &&
           this->index_ == itr.index_;
  }

  auto operator!=(const IndexIterator &itr) const -> bool {
    if (this->index_ == -1 && itr.index_ == -1) {
      return false;
    }
    return this->bpm_ != itr.bpm_ || this->page_guarded_.PageId() != itr.page_guarded_.PageId() ||
           this->index_ != itr.index_;
  }

 private:
  // add your own private member variables here
  ReadPageGuard page_guarded_;
  int index_;
  BufferPoolManager *bpm_;
};

}  // namespace bustub
